package com.yunao.web.controller;

import com.yunao.commons.Exception.YunaoException;
import com.yunao.commons.enums.NeedAlarmEnum;
import com.yunao.commons.enums.ResultEnum;
import com.yunao.commons.utils.ResultVOUtil;
import com.yunao.commons.vo.ResultVO;
import com.yunao.entity.Subject;
import com.yunao.entity.User;
import com.yunao.service.SubjectService;
import com.yunao.service.UserService;
import com.yunao.service.report.Convert;
import com.yunao.service.report.StringUtil;
import com.yunao.web.annotation.UserLoginToken;
import com.yunao.web.form.AlarmForm;
import com.yunao.web.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/subject/alarm/")
@Slf4j
public class AlarmController {

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private UserService userService;

    /**
     * showdoc
     * @catalog API文档/预警模块
     * @title 预警列表
     * @description 获取预警列表
     * @method get
     * @url /subject/alarm/alarmList
     * @return {"code": 0,"msg": "成功","data": [{"address": "gzd@163.com,","method": "弹窗","name": "旅游","endtime": "∞","status": "正在预警"}]}
     * @remark 预警列表
     * @number 01
     */
    @RequestMapping("/alarmList")
    public ResultVO alarmList(HttpServletRequest request){
        String userId = TokenUtil.getTokenUserId();
        List results = new ArrayList();
        List<Subject> subjects = subjectService.findAlarmList(Convert.getInt(userId));
        for (Subject subject:subjects) {
            Map alarm = new HashMap();
            alarm.put("subjectId", subject.getSubjectId());
            alarm.put("name", subject.getSubjectName());
            alarm.put("method", covert(subject.getAlarmMethod()));
            int status = subject.getNeedAlarm();
            if (status == 0) {
                alarm.put("status", "已停止");
            } else
                alarm.put("status", "正在预警");
            String[] period = subject.getAlarmPeriod().split(",");
            if (period[0].equals("custom")){
                alarm.put("period",-1);
                alarm.put("begin",period[1]);
                alarm.put("end",period[2]);
            }else{
                alarm.put("period",period[1]);
                alarm.put("begin",period[2]);
                alarm.put("end",period[3]);
            }
//            alarm.put("endtime",period[period.length-1]);
            alarm.put("address",subject.getAlarmAddrs());
            results.add(alarm);
        }
        return ResultVOUtil.success(results);
    }

    private String covert(String method) {
        List<String> list = Arrays.asList(method.split(","));
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            String ch = list.get(i);
            if (ch.equals("1")){
                sb.append("弹窗");
            }else if (ch.equals("2")){
                if (sb.length()!=0){
                    sb.append("+");
                }
                sb.append("邮件");
            }else if (ch.equals("3")){
                if (sb.length()!=0){
                    sb.append("+");
                }
                sb.append("微信");
            }
        }
        return sb.toString();
    }

    /**
     * showdoc
     * @catalog API文档/预警模块
     * @title 获取单个预警
     * @description 获取单个预警，修改预警的时候，根据专题id获取预警信息回显页面
     * @method get
     * @url /subject/alarm/findOneAlarm
     * @param subjectid 必选 int 专题id
     * @return {"code": 0,"msg": "成功","data": {"period": "0","method": "1","name": "旅游"}}
     * @remark 预警与专题是关联的，所以传入专题id就可以了
     * @number 02
     */

    @RequestMapping("/findOneAlarm")
    public ResultVO findOneAlarm(Integer subjectid){
        Subject subject = subjectService.findOne(subjectid);
        Map alarm = new HashMap();
        alarm.put("name",subject.getSubjectName());
        String[] period = subject.getAlarmPeriod().split(",");
        if (period[0].equals("custom")){
            alarm.put("period",-1);
            alarm.put("begin",period[1]);
            alarm.put("end",period[2]);
        }else{
            alarm.put("period",period[1]);
            alarm.put("begin",period[2]);
            alarm.put("end",period[3]);
        }
        alarm.put("method",subject.getAlarmMethod());
        return ResultVOUtil.success(alarm);
    }



    @UserLoginToken
    @RequestMapping("/addAlarm")
    public ResultVO addAlarm(@Valid AlarmForm alarmForm, BindingResult bindingResult, HttpServletRequest request) {
        if (bindingResult.hasErrors()){
            log.error("【创建预警】参数不正确");
            throw new YunaoException(ResultEnum.PARAM_ERROR.getCode(),
                    bindingResult.getFieldError().getDefaultMessage());
        }
        Subject subject = subjectService.findOne(NumberUtils.toInt(alarmForm.getSubjectId()));
        if (subject==null)
            throw new YunaoException(ResultEnum.SUBJECT_NOT_EXIST);
        List<String> list = Arrays.asList(alarmForm.getAlarmMethod().split(","));
        if ((list.contains("2"))&&(StringUtils.isEmpty(alarmForm.getAlarmAddrs()))) {
            throw new YunaoException(ResultEnum.EMAIL_NOT_EXIET);
        }
        // 预警时间
        String alarmPeriod=getAlarmPeriod(request);

        subject.setNeedAlarm(NeedAlarmEnum.NEED_ALARM.getCode());
        subject.setAlarmCreateDate(new Date());
//        subject.setAlarmFreq(alarmFreq);
//        subject.setAlarmRule(alarmRule);
        subject.setAlarmPeriod(alarmPeriod);
        subject.setAlarmMethod(alarmForm.getAlarmMethod());
        subject.setAlarmAddrs(alarmForm.getAlarmAddrs());
        subjectService.save(subject);

        return ResultVOUtil.success();
    }


    @RequestMapping("/alarmSubjectList")
    public ResultVO withoutAlarmSubject(){
        Map map = new HashMap();
        String userid = TokenUtil.getTokenUserId();
        List<Subject> subjectList = subjectService.findListByUser(Convert.getInt(userid));
        List<Subject> noalarmList = subjectList.stream()
                .filter(e->e.getNeedAlarm()!= NeedAlarmEnum.NEED_ALARM.getCode())
                .collect(Collectors.toList());
        List<Subject> alarmList= subjectList.stream()
                .filter(e->e.getNeedAlarm()== NeedAlarmEnum.NEED_ALARM.getCode())
                .collect(Collectors.toList());
        map.put("alarmSubject",alarmList);
        map.put("noalarmSubject",noalarmList);
        return ResultVOUtil.success(map);
    }


    /**
     * showdoc
     * @catalog API文档/预警模块
     * @title 开启预警
     * @description
     * @method get
     * @url /subject/alarm/openAlarm
     * @param subjectId 必选 int 专题id
     * @return {code: 0,msg: "成功",data: {}}
     * @remark 开启预警
     * @number 05
     */
    @UserLoginToken
    @RequestMapping("/openAlarm")
    public ResultVO open(Integer subjectId,HttpServletRequest request){
        Subject subject = subjectService.findOne(subjectId);
        subject.setNeedAlarm(NeedAlarmEnum.NEED_ALARM.getCode());
        subjectService.save(subject);
        return ResultVOUtil.success();
    }
    /**
     * showdoc
     * @catalog API文档/预警模块
     * @title 关闭预警
     * @description
     * @method get
     * @url /subject/alarm/stopAlarm
     * @param subjectId 必选 int 专题id
     * @return {code: 0,msg: "成功",data: {}}
     * @remark 关闭预警
     * @number 06
     */
    @UserLoginToken
    @RequestMapping("/stopAlarm")
    public ResultVO stop(Integer subjectId,HttpServletRequest request){
        Subject subject = subjectService.findOne(subjectId);
        subject.setNeedAlarm(NeedAlarmEnum.NON_ALARM.getCode());
        subjectService.save(subject);
        return ResultVOUtil.success();
    }

    /**
     * showdoc
     * @catalog API文档/预警模块
     * @title 删除预警
     * @description
     * @method get
     * @url /subject/alarm/deleteAlarm
     * @param subjectId 必选 int 专题id
     * @return {code: 0,msg: "成功",data: {}}
     * @remark 关闭预警
     * @number 04
     */
    @UserLoginToken
    @RequestMapping("/deleteAlarm")
    public ResultVO delete(Integer subjectId,HttpServletRequest request) {
        Subject subject = subjectService.findOne(subjectId);
        subject.setNeedAlarm(0);
        subject.setAlarmFreq(0);
        subject.setAlarmAddrs(null);
        subject.setAlarmCreateDate(null);
        subject.setAlarmPeriod(null);
        subject.setAlarmRule(null);
        subjectService.save(subject);
        return ResultVOUtil.success();
    }

    @UserLoginToken
    @RequestMapping("/deleteAlarms")
    public ResultVO delete(String subjectIds,HttpServletRequest request) {
        int[] ids = Convert.str2int(subjectIds.split(","));
        for (int i = 0; i < ids.length; i++) {
            Subject subject = subjectService.findOne(ids[i]);
            subject.setNeedAlarm(0);
            subject.setAlarmFreq(0);
            subject.setAlarmAddrs(null);
            subject.setAlarmCreateDate(null);
            subject.setAlarmPeriod(null);
            subject.setAlarmRule(null);
            subjectService.save(subject);
        }

        return ResultVOUtil.success();
    }


    // 设置时间
    private String getAlarmPeriod(HttpServletRequest request) {
        int[] array = { -1, 0, 30, 90, 180 };
        int period = NumberUtils.toInt(request.getParameter("period"));
        if (!ArrayUtils.contains(array, period)) {
            throw new IllegalArgumentException("预警时间间隔异常");
        }

        String periodstr = null;
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
        if (period == -1) {
            DateTime beginTime = null, endTime = null;
            try {
                beginTime = DateTime.parse(request.getParameter("begin"),
                        formatter);
                endTime = DateTime
                        .parse(request.getParameter("end"), formatter);
            } catch (Exception e) {

            }
            if (beginTime == null || beginTime.plusDays(1).isBeforeNow()) {
                throw new IllegalArgumentException("预警起始时间错误");
            }
            if (endTime == null || beginTime.isAfter(endTime)) {
                throw new IllegalArgumentException("预警起始时间或结束时间错误");
            }

            periodstr = "custom," + beginTime.toString(formatter) + ","
                    + endTime.toString(formatter);
        } else {
            periodstr = "fixed,"
                    + period
                    + ","
                    + DateTime.now().toString(formatter)
                    + ","
                    + (period == 0 ? "∞" : DateTime.now().plusDays(period)
                    .toString(formatter));
        }
        return periodstr;
    }

    // 选择预警方式
    private String getAlarmMethods(String[] methods){
        if (ArrayUtils.isEmpty(methods)) {
            throw new IllegalArgumentException("请选择预警方式");
        }

        int result = 0;
        for (String method : methods) {
            int n = NumberUtils.toInt(method);
            if (n >= 1 && n <= 4) {
                result += n;
            }
        }
        if (result > 7 || result < 1) {
            // throw new IllegalArgumentException("请选择正确的预警方式");
            return null;
        }
//		System.out.println(result);
        return result + "";
    }

    // 预警地址
    private String[] getAlarmAddrs(String[] addrs){
//        String[] addrs = request.getParameter("addr[]").split(",");
        if (ArrayUtils.isEmpty(addrs)) {
            // throw new IllegalArgumentException("请输入预警地址");
            return null;
        }
        if (addrs.length > 2) {
            return null;
        }
        for (int i = 0; i < addrs.length; i++) {
            for (int j = addrs.length - 1; j > i; j--) {
                if (addrs[i].equals(addrs[j])) {
//                    writer.write("邮箱地址重复");
                    return null;
                }
            }
        }
        String[] result = null;
        for (String addr : addrs) {
            if (StringUtils.isNotBlank(addr)) {
                if (!IsUrl(addr)) {
//                    writer.write("请输入正确的地址");
                    return null;
                }
                result = ArrayUtils.add(result, addr);
            }
        }
        if (ArrayUtils.isEmpty(result)) {
            // throw new IllegalArgumentException("请输入预警地址");
            return null;
        }
        return result;
    }
    public static boolean IsUrl(String str) {
        String regex = "\\w+(\\.\\w)*@\\w+(\\.\\w{2,3}){1,3}";

        return str.matches(regex);
    }
}
